﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace EmbeddedLanguage
{

    public class CompiledStaticExpressionCache_1x0<TInput1>
    {
        [ThreadStatic]
        private static Dictionary<Expression<Action<TInput1>>, Action<TInput1>> Cache;

        private static Dictionary<Expression<Action<TInput1>>, Action<TInput1>> CacheNN
        {
            get
            {
                if (Cache == null) Cache = new Dictionary<Expression<Action<TInput1>>, Action<TInput1>>();
                return Cache;
            }
        }

        public static Action<TInput1> GetCompiledAction(Expression<Action<TInput1>> expr)
        {
            if (!CacheNN.ContainsKey(expr))
            {
                CacheNN[expr] = expr.Compile();
            }
            return CacheNN[expr];
        }
    }

    public class CompiledStaticExpressionCache_2x0<TInput1, TInput2>
    {
        [ThreadStatic]
        private static Dictionary<Expression<Action<TInput1, TInput2>>, Action<TInput1, TInput2>> Cache;

        private static Dictionary<Expression<Action<TInput1, TInput2>>, Action<TInput1, TInput2>> CacheNN
        {
            get
            {
                if (Cache == null) Cache = new Dictionary<Expression<Action<TInput1, TInput2>>, Action<TInput1, TInput2>>();
                return Cache;
            }
        }

        public static Action<TInput1, TInput2> GetCompiledAction(Expression<Action<TInput1, TInput2>> expr)
        {
            if (!CacheNN.ContainsKey(expr))
            {
                CacheNN[expr] = expr.Compile();
            }
            return CacheNN[expr];
        }
    }

    public class CompiledStaticExpressionCache_1x1<TInput1, TOut>
    {
        [ThreadStatic]
        private static Dictionary<Expression<Func<TInput1, TOut>>, Func<TInput1, TOut>> Cache;

        private static Dictionary<Expression<Func<TInput1, TOut>>, Func<TInput1, TOut>> CacheNN
        {
            get
            {
                if (Cache == null) Cache = new Dictionary<Expression<Func<TInput1, TOut>>, Func<TInput1, TOut>>();
                return Cache;
            }
        }

        public static Func<TInput1, TOut> GetCompiledFunc(Expression<Func<TInput1, TOut>> expr)
        {
            if (!CacheNN.ContainsKey(expr))
            {
                CacheNN[expr] = expr.Compile();
            }
            return CacheNN[expr];
        }
    }

    
    public class CompiledStaticExpressionCache_2x1<TInput1, TInput2, TOut>
    {
        [ThreadStatic]
        private static Dictionary<Expression<Func<TInput1, TInput2, TOut>>, Func<TInput1, TInput2, TOut>> Cache;

        private static Dictionary<Expression<Func<TInput1, TInput2, TOut>>, Func<TInput1, TInput2, TOut>> CacheNN
        {
            get
            {
                if (Cache == null) Cache = new Dictionary<Expression<Func<TInput1, TInput2, TOut>>, Func<TInput1, TInput2, TOut>>();
                return Cache;
            }
        }

        public static Func<TInput1, TInput2, TOut> GetCompiledFunc(Expression<Func<TInput1, TInput2, TOut>> expr)
        {
            if (!CacheNN.ContainsKey(expr))
            {
                CacheNN[expr] = expr.Compile();
            }
            return CacheNN[expr];
        }

 

    }
}
